#include "app_device.h"
#include  <fcntl.h>
#include  <unistd.h>
#include  "app_mqtt.h"
#include  "app_buffer.h"
#include  "log.h"
#include "app_common.h"
#include "app_pool.h"
#include "app_message.h"
#include <string.h>
#include <stdlib.h>

static app_device_t *dev;

/**
 * @brief 初始化设备 
 * @return  返回设备指针
 */
app_device_t *app_device_init()
{
    //1  创建设备结构体
     dev = (app_device_t *)malloc(sizeof(app_device_t));
    if(dev == NULL)
    {
        return NULL;
    }
    dev->dev_filename=DEVICE_FILE_NAME;
    dev->dev_fd = open(dev->dev_filename,O_RDWR|O_APPEND);
    if(dev->dev_fd == -1)
    {
        perror("open error");
        log_error("打开蓝牙设备文件失败");
    }
    dev->read_thread=-1;
    dev->post_read=NULL;
    dev->pre_write=NULL;
    dev->is_running=0;
    dev->up_buffer=app_buffer_init();
    dev->down_buffer=app_buffer_init();

    return dev;

}
/**
 * @brief 上行2号步骤 提交给线程池
 * 1 从上行缓冲区读取数据
   2 数据转换 字节数组转换为json
   3  把json发送消息队列 

 */
static void *app_device_up_2_send(void *arg)
{   char read_buffer[100];
    // * 1 从上行缓冲区读取数据
    int read_size=  app_buffer_read(dev->up_buffer,read_buffer,100);

    // 2 数据转换 字节数组转换为json
    char *json= app_message_bytes_to_json(read_buffer,read_size);

    // 3  把json发送消息队列 
    app_mqtt_send(json,strlen(json));

    return NULL;
}

/**
 * @brief 从蓝牙设备文件读取数据 上行1号步骤 独立线程
 * 1 读取蓝牙设备文件中的数据
  2 数据转换  读后预处理
  3 写入上行缓冲区
  4  将上行步骤2 提交给线程池 

 */
static void *app_device_up_1_read(void *arg)
{ 
        //1 读取蓝牙设备文件中的数据 
        int read_size;
        char read_buffer[100];
       while ( 1)  
       {   read_size = read (dev->dev_fd,  read_buffer, 100);
            if( read_size == -1)
            {
                perror("read error");
                log_error("读取蓝牙设备文件失败");
            }
           if( read_size >0) 
           {    
                 
                
                log_info("读取到数据：%d",read_size);
                app_common_bytes_print(read_buffer,read_size);
                //2 数据转换  读后预处理
                if(dev->post_read!=NULL)
                {
                    read_size=  dev->post_read(read_buffer,read_size);
                }
                //  3 写入上行缓冲区
                if(read_size>0)
                {
                    int ret= app_buffer_write(dev->up_buffer,read_buffer,read_size);
                    if (ret == -1)
                    {
                        log_error("上行缓冲区写失败");
                         continue;
                    }
                    // 4  将上行步骤2 提交给线程池 
                    app_pool_submit_task(app_device_up_2_send,NULL);
                    
                }

           }
       }
       return NULL;
}

/**
 * @brief 下行2号步骤 线程池完成
 1 读取下行缓冲区
 2 把字节数组 转为蓝牙格式（写前预处理） 
 3  写入蓝牙设备文件
 */
static  void  *app_device_down_2_write(void *arg)
{
    // 1 读取下行缓冲区
    char buffer[100];
    int read_size= app_buffer_read(dev->down_buffer,buffer,100);

    // 2 把字节数组 转为蓝牙格式（写前预处理） 
    if(dev->pre_write!=NULL)
    {
        read_size=  dev->pre_write(buffer,read_size);
    }
    log_info("向蓝牙设备文件写入数据：");
    app_common_bytes_print(buffer,read_size);
    // 3  写入蓝牙设备文件
    log_info("向蓝牙设备文件写入 :%d , fd :%d",read_size,dev->dev_fd);
    int write_size= write(dev->dev_fd,buffer,read_size);
    if(write_size!=read_size)
    {   
        perror("write error");
        log_error("向蓝牙设备文件写入失败");
    }

    return NULL;

}

/**
 *@brief 下行1号步骤
 1 数据转换 json转字节数组
  2 写入下行缓冲区
3  将下行步骤2 提交线程池

 */
static int app_device_down_1(char *json ,int len)
{
    log_info("接收到mqtt数据:%s",json);
//     1 数据转换 json转字节数组
     char bytes_buff[100];
     int bytes_size= app_message_json_to_bytes(json,bytes_buff,100);
//     2 写入下行缓冲区
      app_buffer_write(dev->down_buffer,bytes_buff,bytes_size);
//   3  将下行步骤2 提交线程池
     app_pool_submit_task(app_device_down_2_write,NULL);

    return 0;
}


/**
 * @brief 启动设备
 * 1  启动从蓝牙设备文件读取的线程 
 * 2  向mqtt模块注册接收到数据的回调函数
 */
void app_device_start()
{    
     //1  启动从蓝牙设备文件读取的线程 
     pthread_create(&dev->read_thread,NULL,app_device_up_1_read,NULL);
     //2  向mqtt模块注册接收到数据的回调函数
     app_mqtt_register_recv_callback(app_device_down_1);
     //3 is_running置1
     dev->is_running=1;
 
}


/**
 * @brief 停止销毁设备
 */
void app_device_destroy()
{
    // 1  销毁缓冲区 
    app_buffer_destroy(dev->up_buffer);
    app_buffer_destroy(dev->down_buffer);

    // 2 关闭文件 
    close(dev->dev_fd);

    // 3 销毁结构体
    free(dev);
}